﻿using HardcoreGame.Common.Players;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.Audio;
using Terraria.GameContent.UI.Elements;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.UI;

namespace HardcoreGame.Common.UI
{

    public class FractureUIState : UIState
    {
        private UIPanel mainPanel;
        private UIImageButton toggleButton;
        private bool isVisible = false;
        private float slideProgress = 0f;
        private const float SlideSpeed = 0.1f;
        private const int HiddenX = -320;
        private const int VisibleX = 20;
        private UIHealthBar headBar;
        private UIHealthBar torsoBar;
        private UIHealthBar leftArmBar;
        private UIHealthBar rightArmBar;
        private UIHealthBar leftLegBar;
        private UIHealthBar rightLegBar;

        public override void OnInitialize()
        {
            mainPanel = new UIPanel();
            mainPanel.Width.Set(300, 0);
            mainPanel.Height.Set(400, 0);
            mainPanel.Left.Set(HiddenX, 0);
            mainPanel.Top.Set(100, 0);
            mainPanel.BackgroundColor = new Color(0, 0, 0, 180);
            mainPanel.BorderColor = new Color(50, 50, 50, 150);
            Append(mainPanel);

            var title = new UIText(Language.GetText("Mods.HardcoreGame.UI.12")) { HAlign = 0.5f };
            title.Top.Set(10, 0);
            mainPanel.Append(title);
            int yOffset = 50;
            int spacing = 60;
            var headImage = new UIImage(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/Head"));
            headImage.Left.Set(20, 0);
            headImage.Top.Set(yOffset, 0);
            headImage.OnLeftClick += (evt, element) => PartClicked(FractureLocation.Head);
            mainPanel.Append(headImage);

            headBar = new UIHealthBar();
            headBar.Left.Set(70, 0);
            headBar.Top.Set(yOffset + 10, 0);
            headBar.Width.Set(200, 0);
            headBar.Height.Set(20, 0);
            mainPanel.Append(headBar);
            yOffset += spacing;
            var torsoImage = new UIImage(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/Torso"));
            torsoImage.Left.Set(20, 0);
            torsoImage.Top.Set(yOffset, 0);
            torsoImage.OnLeftClick += (evt, element) => PartClicked(FractureLocation.Torso);
            mainPanel.Append(torsoImage);
            torsoBar = new UIHealthBar();
            torsoBar.Left.Set(70, 0);
            torsoBar.Top.Set(yOffset + 10, 0);
            torsoBar.Width.Set(200, 0);
            torsoBar.Height.Set(20, 0);
            mainPanel.Append(torsoBar);
            yOffset += spacing;
            var leftArmImage = new UIImage(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/LeftArm"));
            leftArmImage.Left.Set(20, 0);
            leftArmImage.Top.Set(yOffset, 0);
            leftArmImage.OnLeftClick += (evt, element) => PartClicked(FractureLocation.LeftArm);
            mainPanel.Append(leftArmImage);
            leftArmBar = new UIHealthBar();
            leftArmBar.Left.Set(70, 0);
            leftArmBar.Top.Set(yOffset + 10, 0);
            leftArmBar.Width.Set(200, 0);
            leftArmBar.Height.Set(20, 0);
            mainPanel.Append(leftArmBar);
            yOffset += 40;
            var rightArmImage = new UIImage(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/RightArm"));
            rightArmImage.Left.Set(20, 0);
            rightArmImage.Top.Set(yOffset, 0);
            rightArmImage.OnLeftClick += (evt, element) => PartClicked(FractureLocation.RightArm);
            mainPanel.Append(rightArmImage);
            rightArmBar = new UIHealthBar();
            rightArmBar.Left.Set(70, 0);
            rightArmBar.Top.Set(yOffset + 10, 0);
            rightArmBar.Width.Set(200, 0);
            rightArmBar.Height.Set(20, 0);
            mainPanel.Append(rightArmBar);
            yOffset += spacing;
            var leftLegImage = new UIImage(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/LeftLeg"));
            leftLegImage.Left.Set(20, 0);
            leftLegImage.Top.Set(yOffset, 0);
            leftLegImage.OnLeftClick += (evt, element) => PartClicked(FractureLocation.LeftLeg);
            mainPanel.Append(leftLegImage);
            leftLegBar = new UIHealthBar();
            leftLegBar.Left.Set(70, 0);
            leftLegBar.Top.Set(yOffset + 10, 0);
            leftLegBar.Width.Set(200, 0);
            leftLegBar.Height.Set(20, 0);
            mainPanel.Append(leftLegBar);
            yOffset += 40;
            var rightLegImage = new UIImage(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/RightLeg"));
            rightLegImage.Left.Set(20, 0);
            rightLegImage.Top.Set(yOffset, 0);
            rightLegImage.OnLeftClick += (evt, element) => PartClicked(FractureLocation.RightLeg);
            mainPanel.Append(rightLegImage);
            rightLegBar = new UIHealthBar();
            rightLegBar.Left.Set(70, 0);
            rightLegBar.Top.Set(yOffset + 10, 0);
            rightLegBar.Width.Set(200, 0);
            rightLegBar.Height.Set(20, 0);
            mainPanel.Append(rightLegBar);
            toggleButton = new UIImageButton(ModContent.Request<Texture2D>("HardcoreGame/Assets/Textures/BodyParts/Arrow"));
            toggleButton.Width.Set(32, 0);
            toggleButton.Height.Set(32, 0);
            toggleButton.Left.Set(VisibleX + 10, 0);
            toggleButton.Top.Set(150, 0);
            toggleButton.OnLeftClick += (evt, element) => ToggleUI();
            Append(toggleButton);
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (isVisible && slideProgress < 1f)
            {
                slideProgress += SlideSpeed;
                if (slideProgress > 1f) slideProgress = 1f;
                UpdatePanelPosition();
            }
            else if (!isVisible && slideProgress > 0f)
            {
                slideProgress -= SlideSpeed;
                if (slideProgress < 0f) slideProgress = 0f;
                UpdatePanelPosition();
            }
            if (!Main.LocalPlayer.dead && Main.LocalPlayer.active)
            {
                var modPlayer = Main.LocalPlayer.GetModPlayer<FracturePlayer>();
                UpdateHealthBar(headBar, modPlayer.GetPartHealth(FractureLocation.Head));
                UpdateHealthBar(torsoBar, modPlayer.GetPartHealth(FractureLocation.Torso));
                UpdateHealthBar(leftArmBar, modPlayer.GetPartHealth(FractureLocation.LeftArm));
                UpdateHealthBar(rightArmBar, modPlayer.GetPartHealth(FractureLocation.RightArm));
                UpdateHealthBar(leftLegBar, modPlayer.GetPartHealth(FractureLocation.LeftLeg));
                UpdateHealthBar(rightLegBar, modPlayer.GetPartHealth(FractureLocation.RightLeg));
            }
        }

        private void UpdatePanelPosition()
        {
            float x = HiddenX + (VisibleX - HiddenX) * EasingFunction(slideProgress);
            mainPanel.Left.Set(x, 0);
            toggleButton.Left.Set(isVisible ? VisibleX + 300 : VisibleX + 10, 0);
        }

        private static float EasingFunction(float t) => t * t * (3 - 2 * t);

        private static void UpdateHealthBar(UIHealthBar bar, float health)
        {
            bar.SetHealth(health);
            if (health < 0.25f)
                bar.BarColor = Color.Red;
            else if (health < 0.5f)
                bar.BarColor = Color.Orange;
            else if (health < 0.75f)
                bar.BarColor = Color.Yellow;
            else
                bar.BarColor = Color.LimeGreen;
        }

        private void ToggleUI()
        {
            isVisible = !isVisible;
            SoundEngine.PlaySound(SoundID.MenuTick);
        }

        private static void PartClicked(FractureLocation location)
        {
            Player player = Main.LocalPlayer;
            var modPlayer = player.GetModPlayer<FracturePlayer>();

            float health = modPlayer.GetPartHealth(location);
            string status = health switch
            {
                >= 0.75f => "状态良好",
                >= 0.5f => "轻微损伤",
                >= 0.25f => "严重损伤",
                _ => "骨折!"
            };
            Main.NewText($"{location}状态: {status} ({(int)(health * 100)}%)",
                health > 0.5f ? Color.White : health > 0.25f ? Color.Yellow : Color.Red);
        }
    }
}